package com.exchange.service;

import com.exchange.dto.OrderDto;
import com.exchange.entity.Order;
import com.exchange.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class OrderService {
    
    @Autowired
    private OrderRepository orderRepository;
    
    @Autowired
    private ResourceLimitService resourceLimitService;
    
    public Optional<OrderDto> findById(Long id) {
        return orderRepository.findById(id)
                .map(OrderDto::fromEntity);
    }
    
    public Optional<OrderDto> findByOrderNumber(String orderNumber) {
        return orderRepository.findByOrderNumber(orderNumber)
                .map(OrderDto::fromEntity);
    }
    
    public List<OrderDto> findByMerchantId(Long merchantId) {
        return orderRepository.findByMerchantId(merchantId)
                .stream()
                .map(OrderDto::fromEntity)
                .collect(Collectors.toList());
    }
    
    public OrderDto createOrder(Order order, Long merchantId) {
        // Check if merchant has reached order limit
        if (!resourceLimitService.isWithinOrderLimit(merchantId, null)) {
            throw new RuntimeException("Merchant has reached the maximum number of orders for this month");
        }
        
        order.setMerchantId(merchantId);
        order.setOrderNumber(generateOrderNumber());
        order.setCreatedAt(java.time.LocalDateTime.now());
        order.setUpdatedAt(java.time.LocalDateTime.now());
        
        Order savedOrder = orderRepository.save(order);
        return OrderDto.fromEntity(savedOrder);
    }
    
    public Optional<OrderDto> updateOrderStatus(Long id, Order.OrderStatus newStatus) {
        Optional<Order> existingOrder = orderRepository.findById(id);
        if (existingOrder.isPresent()) {
            Order order = existingOrder.get();
            
            // Update status-specific timestamps
            switch (newStatus) {
                case SHIPPED:
                    if (order.getOrderStatus() == Order.OrderStatus.CONFIRMED || 
                        order.getOrderStatus() == Order.OrderStatus.PROCESSING) {
                        order.setShippedAt(java.time.LocalDateTime.now());
                    }
                    break;
                case DELIVERED:
                    if (order.getOrderStatus() == Order.OrderStatus.SHIPPED) {
                        order.setDeliveredAt(java.time.LocalDateTime.now());
                    }
                    break;
                case CANCELLED:
                    order.setCancelledAt(java.time.LocalDateTime.now());
                    break;
            }
            
            order.setOrderStatus(newStatus);
            order.setUpdatedAt(java.time.LocalDateTime.now());
            
            Order updatedOrder = orderRepository.save(order);
            return Optional.of(OrderDto.fromEntity(updatedOrder));
        }
        return Optional.empty();
    }
    
    public List<OrderDto> findByStatus(Order.OrderStatus status) {
        // In a real implementation, this would be for all merchants or filtered by admin
        // For now, returning empty list
        return new java.util.ArrayList<>();
    }
    
    public List<OrderDto> findByMerchantIdAndStatus(Long merchantId, Order.OrderStatus status) {
        return orderRepository.findByMerchantIdAndOrderStatus(merchantId, status)
                .stream()
                .map(OrderDto::fromEntity)
                .collect(java.util.stream.Collectors.toList());
    }
    
    public boolean deleteOrder(Long id) {
        if (orderRepository.existsById(id)) {
            orderRepository.deleteById(id);
            return true;
        }
        return false;
    }
    
    private String generateOrderNumber() {
        // Generate a unique order number (in a real implementation, you might want to use a more sophisticated algorithm)
        return "ORD" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
    }
}